<?php

namespace App\Http\Repositories\UserManage;

use App\Http\Repositories\Relation\ResourceObjectRepo;
use App\Http\Repositories\Relation\UserRoleRepo;
use App\Http\Repositories\Repository;
use App\Models\User;
use App\Traits\HelpFunctions;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;

/**
 * 用户管理
 */
class UserRepo extends Repository
{
    use HelpFunctions;

    const MODEL = User::class;

    public function search(array $params)
    {
        // 'name',
        // 'nickname',
        // 'gender',
        // 'phone',
        // 'card_id',
        // 'role_id',
        // 'begin_time',
        // 'end_time',
        $query = $this->query();
        if (!empty($params['name'])) {
            $query->where('name', 'like', '%' . $params['name'] . '%');
        }
        if (!empty($params['nickname'])) {
            $query->where('nickname', 'like', '%' . $params['nickname'] . '%');
        }
        if (!empty($params['gender'])) {
            $query->where('gender', $params['gender']);
        }
        if (!empty($params['phone'])) {
            $query->where('phone', 'like', '%' . $params['phone'] . '%');
        }
        if (!empty($params['nickname'])) {
            $query->where('card_id', 'like', '%' . $params['card_id'] . '%');
        }
        if (!empty($params['role_ids'])) {
            $user_ids = app(UserRoleRepo::class)->getUserIdsByRoleIds($params['role_ids']);
            $query->whereIn('id', $user_ids);
        }

        if (!empty($params['begin_time'])) {
            $query->where('created_at', '>=', $params['begin_time']);
        }

        if (!empty($params['end_time'])) {
            $query->where('created_at', '<=', $params['end_time']);
        }

        $query->with('roles');

        return $this->paginate($query, $params["paginate"] ?? true, $params["page_num"] ?? 10);
    }

    public function getOneById($id)
    {
        $query = $this->query()
            ->select('id', 'name', 'phone', 'nickname', 'avatar', 'gender', 'card_id')
            ->where('id', $id)
            ->with('roles')
            ->first();

        return !empty($query) ? $query->toArray() : [];
    }

    public function createOne(array $params)
    {
        $keys = [
            'name',
            'gender',
            'phone',
            'card_id',
            'password',
            'open_id',
        ];
        $user_args = $this->getArrayByKeys($params, $keys);

        !empty($user_args['password']) && $user_args['password'] = Hash::make($user_args['password']);

        DB::beginTransaction();
        try {
            $user = parent::createOne($user_args);
            $user_id = $user->id;
            $role = app(RoleRepo::class)->getByAlias('demand');
            $role_id = $role->id;
            app(UserRoleRepo::class)->create($user_id, $role_id);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            abort(500, $e->getMessage());
        }

        return $this->getOneById($user_id);
    }

    public function deleteById(int $id)
    {
        DB::beginTransaction();
        try {
            $user = $this->query()->findOrFail($id);
            $user->delete();
            $user->roles()->detach();
            DB::commit();
        } catch (ModelNotFoundException $e) {
            DB::rollBack();
            abort(422, "不存在该用户");
        } catch (\Exception $e) {
            DB::rollBack();
            abort(500, $e->getMessage());
        }
    }

    public function editById(int $id, array $params)
    {
        $keys = [
            'name',
            'gender',
            'phone',
            'card_id',
            'password',
        ];
        $user_args = $this->getArrayByKeys($params, $keys);

        !empty($user_args['password']) && $user_args['password'] = Hash::make($user_args['password']);

        DB::beginTransaction();
        try {
            parent::editById($id, $user_args);
            // $user->roles()->detach(); //先删除关系
            // $user->roles()->attach($role_ids);
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            abort(500, $e->getMessage());
        }

        return $this->getOneById($id);
    }

    /**
     * 实名认证用户
     */
    public function realAuth(array $params, $user_id)
    {
        if (empty($this->getOneById($user_id))) abort(422, "该用户不存在");
        $user_args = [];
        if (!empty($params["card_id"])) $user_args["card_id"] = $params["card_id"];
        if (!empty($params["name"])) $user_args["name"] = $params["name"];
        $resource_args = [];
        if (!empty($params["resources"])) {
            $resource_args[] = [
                "link" => $params["resources"]["link"],
                "object_id" => $user_id,
                "type" => config("project.resource.user_card_id"),
                "sort" => $params["resources"]["sort"] ?? 1,
            ];
        }
        if (!empty($resource_args)) $resource_delete_args = ["type" => config("project.resource.user_card_id"), "object_id" => $user_id];

        DB::beginTransaction();
        try {
            //更新用户card_id
            $user = $this->editById($user_id, $user_args);

            //删除用户身份证资源
            if (!empty($resource_delete_args)) app(ResourceObjectRepo::class)->deleteByConditions($resource_delete_args);
            if (!empty($resource_args)) app(ResourceObjectRepo::class)->createMany($resource_args);
            //添加身份证图片资源
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            abort(500, $e->getMessage());
        }
    }
}
